Dialout API
Your dialer application calls the Dialout API to have Live Hub place an outbound call and connect it to a bot. Enable the feature and create the routing rule first. See Outbound calling.
Authentication
The dialout endpoint uses HTTP Basic authentication with the API client's credentials: the client ID as the username, the client secret as the password. This is not the OAuth bearer token the rest of the REST API uses. There is no token to obtain first.
Authorization: Basic {BASE64_CLIENT_ID_AND_SECRET}
With curl, -u builds that header for you:
-u "{CLIENT_ID}:{CLIENT_SECRET}"
Trigger the call
Send a POST request to /api/v1/actions/dialout, with the Authorization header
described in Authentication. The base URL is
https://livehub.audiocodes.io.
The JSON body takes these properties:
| Property | Type | Description |
|---|---|---|
bot
|
string | ID of the bot connection to connect the call to. |
target
|
string | URI of the person being called. See Target URIs. |
caller
|
string | User part of the caller ID. The phone number you purchased is used as the caller ID. |
callerHost
|
string | Optional. Host part of the caller ID. Filled with an arbitrary value if omitted. |
callerDisplayName
|
string | Optional. Display name for the caller ID. |
notifyUrl
|
string | Optional. Absolute URL Live Hub posts call status to. HTTPS means the connection is secured with TLS. No URL, no notifications. See Call status notifications. |
sipHeaders
|
array | Optional. Custom SIP headers to add to the start message and the outgoing INVITE, on top of those configured in the bot. See Custom SIP headers. |
metadata
|
object | Optional. Data to pass to the bot, such as the name of the person being called. Arrives as dialoutMetadata. See Metadata on call initiation. |
answerTimeoutSec
|
number | Optional. Seconds to wait for an answer, 1 to 300. Past that the call is marked failed with reason no-answer. Default 20. |
machineDetection
|
string | Optional. disabled (default), disconnect, or detect. See Machine detection. |
voicemailEndTimeoutSec
|
number | Optional. With machineDetection set to detect, how long to wait for the answering machine's beep before telling the bot to start speaking anyway. Default 20. |
POST /api/v1/actions/dialout HTTP/1.1
Host: livehub.audiocodes.io
Content-Type: application/json;charset=UTF-8
Authorization: Basic {BASE64_CLIENT_ID_AND_SECRET}
{
"bot": "UUID",
"target": "tel:+123456789",
"caller": "1-800-111-111",
"notifyUrl": "https://my-app.example.com/call/454/notify",
"machineDetection": "detect",
"voicemailEndTimeoutSec": 20,
"metadata": {
"participantName": "Alice"
}
}
Target URIs
target takes one of two forms:
- A SIP URI, as defined in RFC 3261 —
sip:+14155550100@example.com;user=phoneorsip:alice@example.com. - A tel URI, as defined in RFC 3966 —
tel:+14155550100.
Live Hub forwards the URI to the SBC, which routes on it as the DestURI, and passes it
to the bot in the outboundTarget field of the initial event.
Custom SIP headers
sipHeaders is an array of name and value pairs. They are added to the headers already
configured on the bot connection through dialoutSipHeaders.
[
{ "name": "{header name}", "value": "{header value}" },
{ "name": "{header name 2}", "value": "{header value 2}" }
]
Response
200 OK means the call was triggered, not that it was placed or answered. Use
call status notifications to find out what happened.
| Property | Type | Description |
|---|---|---|
conversationId
|
string | UUID of the new conversation. Use it to correlate multi-step interactions. |
callId
|
string | UUID of this specific call. Use it with status and control APIs that take a call ID. |
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
{
"conversationId": "daf0c30f-e7a7-4644-b20b-667676b70615",
"callId": "64344a82-34d9-463f-a23f-11bb16e31dcf"
}
Errors come back as 400 for an invalid request, 401 for an authentication failure,
or 500 for an internal error:
HTTP/1.1 400 Bad Request
Content-Type: application/json;charset=UTF-8
{
"error": "request should have required property 'bot'"
}
Events the bot receives
Dialout initiated
If sendEventsToBot on the bot connection includes dialoutInitiated, Live Hub sends
the bot this event as the call is initiated, before it is answered. It carries the same
parameters as the initial event, so the bot has the call's details even when the call
goes on to fail.
{
"type": "event",
"name": "dialoutInitiated",
"parameters": {
"callee": "+123456789",
"caller": "1-800-111-111",
"dialoutMetadata": {
"participantName": "Alice"
}
}
}
Metadata on call initiation
When the person answers, Live Hub sends the bot the call-initiation event, carrying
whatever your dialer put in metadata. Where the metadata arrives depends on the
framework.
AudioCodes Bot API. The metadata arrives in dialoutMetadata, inside parameters:
{
"type": "event",
"name": "start",
"parameters": {
"callee": "+123456789",
"caller": "1-800-111-111",
"dialoutMetadata": {
"participantName": "Alice"
}
}
}
Microsoft Bot Framework. The metadata arrives in dialoutMetadata, inside
channelData:
{
"type": "event",
"name": "channel",
"value": "telephony",
"channelData": {
"callee": "+123456789",
"caller": "1-800-111-111",
"dialoutMetadata": {
"participantName": "Alice"
}
},
"from": {
"id": "12345678"
},
"locale": "en-US"
}
Google Dialogflow CX and ES. The metadata arrives in the dialoutMetadata
parameter of the WELCOME event:
{
"queryInput": {
"event": {
"languageCode": "en-US",
"name": "WELCOME",
"parameters": {
"callee": "+123456789",
"caller": "1-800-111-111",
"dialoutMetadata": {
"participantName": "Alice"
}
}
}
}
}
To use a field in the response text, reference it as
#WELCOME.dialoutMetadata.participantName on Dialogflow ES. On Dialogflow CX, the
fields also arrive in the event-WELCOME session parameter:
$session.params.event-WELCOME.dialoutMetadata.participantName
Call status notifications
Set notifyUrl on the dialout request, and Live Hub sends the call's progress to that
URL as JSON.
| Property | Type | Description |
|---|---|---|
conversationId
|
string | UUID of the conversation, matching the one in the trigger response. |
status
|
string | answered; completed, disconnected after being answered; or failed, ended before it was answered. |
reasonCode
|
string | Why it failed or completed. See below. |
reason
|
string | Free text describing the reason, such as the SIP Reason header. |
connectTime
|
string | When the person picked up. |
callDuration
|
number | Seconds from connectTime to the end of the call. |
sbcSessionID
|
string | The SBC session ID. Sent on completed only. |
botOperationResult
|
string | Value the bot set in botOperationResult. Sent on completed or failed, if the bot set it. |
botOperationData
|
string | Value the bot set in botOperationData. Sent on completed or failed, if the bot set it. |
On a failed call, reasonCode takes one of these values:
| Value | Meaning |
|---|---|
no-answer
|
Nobody answered: answerTimeoutSec expired, or SIP timed out. |
busy
|
The number was busy. |
declined
|
The person rejected the call. |
error
|
Something went wrong before the call was answered, such as an invalid number. |
On a completed call, reasonCode takes one of these values:
| Value | Meaning |
|---|---|
bot-disconnected
|
The bot side hung up. |
client-disconnected
|
The person hung up. |
transferred
|
The call to the bot ended after being transferred. |
machine-detected
|
An answering machine or fax was detected. |
error
|
The call dropped on an unexpected error. |
POST /call/454/notify HTTP/1.1
Host: my-app.example.com
Content-Type: application/json;charset=UTF-8
{
"conversationId": "daf0c30f-e7a7-4644-b20b-667676b70615",
"status": "failed",
"reasonCode": "busy",
"reason": "SIP ;cause=486 ;text=\"Busy Here\""
}
Live Hub sends this POST with no authorization header. Include a unique identifier in
the notifyUrl itself so that your server can distinguish genuine notifications from
anything else.
Speech recognition on connect
By default, the first thing the person says when they answer, "Hello" for example, is not sent to speech-to-text. The start message that Live Hub sends the bot then carries no recognition. That avoids speech-to-text charges when the bot speaks first anyway.
To have Live Hub recognize that first utterance and send it to the bot, set 'Start recognition on connect' to Enabled on the bot connection's Outbound Calling tab. See Outbound calling.
If barge-in is enabled, recognition starts regardless of this setting.
Machine detection
Live Hub can watch the audio as soon as an outbound call is answered and determine
whether it reached a person, an answering machine, or a fax. Set machineDetection on
the dialout request to choose what happens next.
| Value | What happens |
|---|---|
disabled
|
Default. No detection, and the call is never disconnected for this reason. |
disconnect
|
Disconnect the call when either a fax or an answering machine is detected. |
detect
|
Disconnect on a fax; on an answering machine, let the bot leave a message. |
Leave a message on an answering machine
With machineDetection set to detect and an answering machine detected, Live Hub
sends the bot two events rather than disconnecting the call.
The first event reports that Live Hub heard an answering machine:
{
"type": "event",
"name": "machineDetection",
"value": "voicemail-prompt-start"
}
The second event, sent once Live Hub hears the beep or once voicemailEndTimeoutSec
expires, tells the bot that it can start speaking:
{
"type": "event",
"name": "machineDetection",
"value": "voicemail-prompt-end-beep"
}
The AudioCodes Bot API and the Microsoft Bot Framework receive both events in that form. Dialogflow CX and ES receive the same values as event parameters:
{
"queryInput": {
"event": {
"languageCode": "en-US",
"name": "machineDetection",
"parameters": {
"value": "voicemail-prompt-start"
}
}
}
}
Disconnect on machine detection
With machineDetection set to disconnect, Live Hub ends the call as soon as it
detects a machine. The notification carries a reasonCode of machine-detected and a
reason of either voicemail detected or fax detected:
{
"conversationId": "daf0c30f-e7a7-4644-b20b-667676b70615",
"status": "completed",
"reasonCode": "machine-detected",
"reason": "fax detected"
}